package com.ksyun.campus.dataserver.controller;

import cn.hutool.core.util.ObjectUtil;
import com.ksyun.campus.common.domain.RepairBody;
import com.ksyun.campus.common.domain.ReplicaData;
import com.ksyun.campus.dataserver.services.DataService;
import com.ksyun.campus.dataserver.services.RegistService;
import com.sun.org.apache.regexp.internal.RE;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.List;

@RestController("/")
public class DataController {

    @Autowired
    private DataService dataService;
    @Autowired
    private RegistService registService;


    @GetMapping("close")
    public ResponseEntity close(@RequestHeader String fileSystem, @RequestParam String path) {
        List<ReplicaData> list = dataService.close(fileSystem, path);
        return ResponseEntity.ok(list);
    }


    /**
     *
     * @param cpath 完整的路径 /metadata/volume/{普通显示的路径}  -> 需要变成  volume-aaa-bbb.jpg 截去 /metadata/
     * @return
     */
    @GetMapping("checkReplica")
    public ResponseEntity checkReplica(@RequestParam String cpath){
        return ResponseEntity.ok(dataService.check(cpath));
    }

    /**
     * 修复数据
     *
     * @return 返回修复好之后的三个节点信息
     */
    @PostMapping("repair")
    public ResponseEntity repair(@RequestBody RepairBody repairBody) {
        dataService.repair(repairBody.getRepairNode(), repairBody.getCpath());
        return ResponseEntity.ok().build();
    }


    /**
     * 修复数据
     *
     * @param fileSystem
     * @param path
     * @return 返回修复好之后的三个节点信息
     */
    @GetMapping("delete")
    public ResponseEntity delete(@RequestHeader String fileSystem, @RequestParam String path, @RequestParam int size) {
        boolean delete = dataService.delete(fileSystem, path, size);
        if (delete) {
            return ResponseEntity.ok().build();
        }
        return ResponseEntity.status(500).body("删除失败");
    }

    /**
     * 同步数据 - 数据节点内部调用 做数据同步的
     *
     * @param request
     * @param fileSystem
     * @param path
     * @param offset
     * @param length
     * @return
     * @throws IOException
     */
    @PostMapping("sync")
    public ResponseEntity sync(HttpServletRequest request, @RequestHeader String fileSystem, @RequestParam String path, @RequestParam int offset, @RequestParam int length) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        dataService.sync(inputStream, fileSystem, path, offset, length);
        //返回节点信息 List<ReplicaData>
        return ResponseEntity.ok().build();
    }


    /**
     * 1、读取request content内容并保存在本地磁盘下的文件内
     * 2、同步调用其他ds服务的write，完成另外2副本的写入
     * 3、返回写成功的结果及三副本的位置
     *
     * @param fileSystem fileSystem就可以相当于你本地磁盘的 c盘、d盘、e盘等，这个维度的概念
     * @param path       保存的路径 /demo/aaa  转为  -demo-aaa
     * @param offset     偏移量
     * @param length     文件大小
     * @return
     */
    @PostMapping("write")
    public ResponseEntity writeFile(HttpServletRequest request, @RequestHeader String fileSystem, @RequestParam String path, @RequestParam int offset, @RequestParam int length) throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        dataService.write(inputStream, fileSystem, path, offset, length);
        return ResponseEntity.ok().build();
    }

    /**
     * 在指定本地磁盘路径下，读取指定大小的内容后返回
     *
     * @param fileSystem
     * @param path
     * @param offset
     * @param length
     * @return
     */
    @RequestMapping("read")
    public ResponseEntity<InputStreamResource> readFile(@RequestHeader String fileSystem, @RequestParam String path, @RequestParam int offset, @RequestParam int length) {
        FileInputStream read = dataService.read(fileSystem, path);
        if (ObjectUtil.isNull(read)) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        InputStreamResource resource = new InputStreamResource(read);
        return ResponseEntity.ok().body(resource);
    }

    /**
     * 关闭退出进程
     */
    @RequestMapping("shutdown")
    public void shutdownServer() {
        registService.unregister();
        System.exit(-1);
    }
}
